<template>
  <div>
    <!-- Breadcrumb Navigation area -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/home' }">Home</el-breadcrumb-item>
      <el-breadcrumb-item>Goods</el-breadcrumb-item>
      <el-breadcrumb-item>Params</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- card view area -->
    <el-card>
      <!-- warning! -->
      <el-alert
        title="Only allowed setting params for 3 level category!"
        type="warning"
        show-icon
        :closable="false"
        effect="dark"
        center
      ></el-alert>
      <!-- goods categoty select -->
      <el-row class="cat_option">
        <span>goods categoty choose:</span>
        <!-- Cascader of goods category -->
        <el-cascader
          :options="cateList"
          :props="cateCascaderProps"
          v-model="selectedCatekeys"
          @change="cateSelectedChange"
          clearable
        ></el-cascader>
      </el-row>
      <!-- Tabs -->
      <el-tabs v-model="activeTabName" @tab-click="handleTabClick">
        <!-- add dynamic params pane -->
        <el-tab-pane label="Dynamic Params" name="many">
          <el-button
            type="primary"
            :disabled="isAddDiabled"
            @click="addParamDialogVisible = true"
          >Add Param</el-button>
          <!-- Table -->
          <el-table :data="dynicParamList" border stripe>
            <el-table-column type="expand" label="-">
              <template slot-scope="sp">
                <!-- Render tags in loop -->
                <el-tag
                  v-for="(item, idx) in sp.row.attr_vals"
                  :key="idx"
                  closable
                  @close="handleTagClose(idx, sp.row)"
                >{{item}}</el-tag>
                <!-- input text box -->
                <el-input
                  class="input-new-tag"
                  v-if="sp.row.inputVisible"
                  v-model="sp.row.inputValue"
                  ref="saveTagInput"
                  size="small"
                  @keyup.enter.native="handleInputConfirm(sp.row)"
                  @blur="handleInputConfirm(sp.row)"
                ></el-input>
                <!-- add btn -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(sp.row)"
                >+ New Tag</el-button>
              </template>
            </el-table-column>
            <el-table-column type="index"></el-table-column>
            <el-table-column label="Attr Name" prop="attr_name"></el-table-column>
            <el-table-column label="Opeating">
              <template slot-scope="sp">
                <el-button
                  type="primary"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditParamDialog(sp.row)"
                >Edit</el-button>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="deleteParamById(sp.row)"
                >Delete</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
        <!-- add static attrs pane -->
        <el-tab-pane label="Static Attrs" name="only">
          <el-button
            type="primary"
            :disabled="isAddDiabled"
            @click="addParamDialogVisible = true"
          >Add Attr</el-button>
          <!-- Table -->
          <el-table :data="staticAttrList" border stripe>
            <el-table-column type="expand" label="-">
              <template slot-scope="sp">
                <!-- Render tags in loop -->
                <el-tag
                  v-for="(item, idx) in sp.row.attr_vals"
                  :key="idx"
                  closable
                  @close="handleTagClose(idx, sp.row)"
                >{{item}}</el-tag>
                <!-- input text box -->
                <el-input
                  class="input-new-tag"
                  v-if="sp.row.inputVisible"
                  v-model="sp.row.inputValue"
                  ref="saveTagInput"
                  size="small"
                  @keyup.enter.native="handleInputConfirm(sp.row)"
                  @blur="handleInputConfirm(sp.row)"
                ></el-input>
                <!-- add btn -->
                <el-button
                  v-else
                  class="button-new-tag"
                  size="small"
                  @click="showInput(sp.row)"
                >+ New Tag</el-button>
              </template>
            </el-table-column>
            <el-table-column type="index"></el-table-column>
            <el-table-column label="Attr Name" prop="attr_name"></el-table-column>
            <el-table-column label="Opeating">
              <template slot-scope="sp">
                <el-button
                  type="primary"
                  icon="el-icon-edit"
                  size="mini"
                  @click="showEditParamDialog(sp.row)"
                >Edit</el-button>
                <el-button
                  type="danger"
                  icon="el-icon-delete"
                  size="mini"
                  @click="deleteParamById(sp.row)"
                >Delete</el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </el-card>

    <!-- add param dialog -->
    <el-dialog
      :title="'Add ' + titleText"
      :visible.sync="addParamDialogVisible"
      width="47%"
      @close="closeAddParamDialog"
    >
      <el-form
        :model="addParamForm"
        :rules="addParamFormRules"
        ref="addParamFormRef"
        label-width="100px"
      >
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="addParamForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="addParamDialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="addParam">I Sure</el-button>
      </span>
    </el-dialog>

    <!-- edit param dialog -->
    <el-dialog :title="'Edit ' + titleText" :visible.sync="editParamDialogVisible" width="47%">
      <el-form
        :model="editParamForm"
        :rules="addParamFormRules"
        ref="editParamFormRef"
        label-width="100px"
      >
        <el-form-item :label="titleText" prop="attr_name">
          <el-input v-model="editParamForm.attr_name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="editParamDialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="updateParam">I Sure</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cateList: [],
      /* cascader config object */
      cateCascaderProps: {
        expandTrigger: 'hover',
        value: 'cat_id',
        label: 'cat_name',
        children: 'children'
      },
      selectedCatekeys: [],
      /* actived tab pane name */
      activeTabName: 'many',
      dynicParamList: [],
      staticAttrList: [],
      addParamDialogVisible: false,
      addParamForm: {
        attr_name: ''
      },
      addParamFormRules: {
        attr_name: [
          {
            required: true,
            message: 'Please enter a category name',
            trigger: 'blur'
          }
        ]
      },
      editParamDialogVisible: false,
      editParamForm: {
        attr_name: ''
      }
    }
  },
  methods: {
    async getCateList() {
      const rs = await this.$http.get('categories')
      if (rs.meta.status !== 200) {
        return this.$msg.error('Goods categories get faild!')
      }
      this.cateList = rs.data
      // console.log(this.cateList)
    },
    async getParamsList(cateId, sel) {
      const rs = await this.$http.get(`categories/${cateId}/attributes`, {
        params: {
          sel: sel
        }
      })
      if (rs.meta.status !== 200) return this.$msg.error(rs.meta.msg)
      /* split attr values to array */
      rs.data.forEach(item => {
        item.attr_vals = item.attr_vals === '' ? [] : item.attr_vals.split(' ')
        /* add a bool for controll input-text-box visible attr */
        item.inputVisible = false
        /* input-text-box input value */
        item.inputValue = ''
      })
      if (sel === 'many') {
        this.dynicParamList = rs.data
      } else if (sel === 'only') {
        this.staticAttrList = rs.data
      }
      // console.log(rs.data)
    },
    cateSelectedChange() {
      /* if selected catrgory not 3 level, reset it */
      if (this.selectedCatekeys.length !== 3) {
        this.dynicParamList = this.staticAttrList = []
        this.selectedCatekeys = []
        this.$msg.info('must select a 3 level category!')
        return
      }
      /* selected OK, get params */
      this.getParamsList(this.selectedCateId, this.activeTabName)
    },
    /* Tab pane click event handler */
    handleTabClick() {
      /* if selected catrgory not 3 level, noting to do */
      if (this.selectedCatekeys.length !== 3) return
      /* get params */
      this.getParamsList(this.selectedCateId, this.activeTabName)
    },
    closeAddParamDialog() {
      this.$refs.addParamFormRef.resetFields()
    },
    addParam() {
      this.$refs.addParamFormRef.validate(async valid => {
        if (!valid) return
        const rs = await this.$http.post(
          `categories/${this.selectedCateId}/attributes`,
          {
            attr_name: this.addParamForm.attr_name,
            attr_sel: this.activeTabName
          }
        )
        if (rs.meta.status !== 201) return this.$msg.error(rs.meta.msg)
        this.$msg.success(rs.meta.msg)
        this.addParamDialogVisible = false
        this.getParamsList(this.selectedCateId, this.activeTabName)
      })
    },
    showEditParamDialog(param) {
      this.editParamDialogVisible = true
      this.editParamForm = param
    },
    updateParam() {
      this.$refs.editParamFormRef.validate(async valid => {
        if (!valid) return
        const rs = await this.$http.put(
          `categories/${this.selectedCateId}/attributes/${this.editParamForm.attr_id}`,
          this.editParamForm
        )
        if (rs.meta.status !== 200) return this.$msg.error(rs.meta.msg)
        this.$msg.success(rs.meta.msg)
        this.getParamsList(this.selectedCateId, this.activeTabName)
        this.editParamDialogVisible = false
      })
    },
    async deleteParamById(param) {
      /* pop window  ask user */
      const confirmResult = await this.$confirm(
        'You will be deleting {' +
          param.attr_name +
          '} ' +
          this.titleText +
          ', the operation unrecoverable, you sure?',
        'Warning',
        {
          confirmButtonText: 'I Sure',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }
      ).catch(err => err)

      /* if user cancel: tip & do noting */
      if (confirmResult !== 'confirm') {
        return this.$msg.info('Canceled')
      }
      /* delete param from server */
      const rs = await this.$http.delete(
        `categories/${this.selectedCateId}/attributes/${param.attr_id}`
      )
      if (rs.meta.status !== 200) this.$msg.error(rs.meta.msg)
      this.$msg.success(rs.meta.msg)
      this.getParamsList(this.selectedCateId, this.activeTabName)
    },
    async handleInputConfirm(param) {
      /* input value illegal, clean */
      param.inputValue = param.inputValue.trim()
      if (param.inputValue.length === 0) {
        param.inputValue = ''
      } else {
        /* get input value & push to attr_vals */
        param.attr_vals.push(param.inputValue)
        param.inputValue = ''
        /* push to server */
        this.saveParamValues(param)
      }
      /* hide input-text-box */
      param.inputVisible = false
    },
    async saveParamValues(param) {
      /* push to server */
      const rs = await this.$http.put(
        `categories/${this.selectedCateId}/attributes/${param.attr_id}`,
        {
          attr_name: param.attr_name,
          attr_sel: param.attr_sel,
          attr_vals: param.attr_vals.join(' ')
        }
      )
      if (rs.meta.status !== 200) {
        /* cancel just operation */
        param.attr_vals.pop(param.inputValue)
        return this.$msg.error(rs.meta.msg)
      }
      this.$msg.success(rs.meta.msg)
      param = rs.data
    },
    showInput(param) {
      param.inputVisible = true
      /* this.$nextTick: 当页面上元素被重新渲染之后，才会执行回调函数 */
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },
    /* delete option of param  */
    handleTagClose(idx, param) {
      param.attr_vals.splice(idx, 1)
      this.saveParamValues(param)
    }
  },
  computed: {
    isAddDiabled() {
      return this.selectedCatekeys.length === 0
    },
    selectedCateId() {
      if (this.selectedCatekeys.length === 3) {
        return this.selectedCatekeys[3 - 1]
      }
      return null
    },
    titleText() {
      if (this.activeTabName === 'many') {
        return 'Dynic Param'
      } else if (this.activeTabName === 'only') {
        return 'Static Attr'
      }
      return 'NONE'
    }
  },
  created() {
    this.getCateList()
  }
}
</script>

<style lang="less" scoped>
.cat_option {
  margin: 17px 0;
}
.el-tag {
  margin: 7px;
}
.input-new-tag {
  width: 135px;
}
</style>
